package console;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferStrategy;
import java.util.Random;
import java.util.regex.Pattern;

import chooser.ChooseMenu;
import chooser.GameFrame;

public class GameStart extends GameFrame implements Runnable, KeyListener
{
	private static final long serialVersionUID = 5642619743815256222L;
	
	private final int EXIT = 0;
	private final int BACK = 1;

	private Thread game;
	private boolean isRunning = false;
	private int width, height;
	private BufferStrategy myStrategy;
//	private GraphicsDevice myDevice;
//	private Graphics graphics;
	
	private final int FPS = 50;
	private int sleepTime;
	
	private Sprite[] objList;
	private final int robotNum = 50;
	private Random random;
	
	private CmdLine cmdLine;
	
	/**
	 *  Player, only a square currently
	 */
	private Sprite player;

	public GameStart(int i)
	{
		if (i != 0)
		{
			showon();
		}
	}
	
	private void shutDown(int i)
	{
		if (i != EXIT)
		{
			setIgnoreRepaint(false);
			this.removeKeyListener(this);
			this.setVisible(false);
			isRunning = false;
			game = null;
			this.dispose();
			ChooseMenu.getInstance().setVisible(true);
		}
		else
		{
			this.getOwner().setIgnoreRepaint(false);
			System.exit(0);
		}
//		if (i != EXIT)
//		{
//			ChooseMenu.getInstance().setVisible(true);
//		}
//		else
//		{
//			if (myStrategy != null)
//				myStrategy.dispose();
//			if (myDevice != null)
//			{
//				myDevice.setFullScreenWindow(null);
//				myDevice = null;
//			}
//			if (graphics != null)
//			{
//				graphics.dispose();
//			}
//			try
//			{
//				Thread.sleep(300);
//			}
//			catch (InterruptedException ie)
//			{
//				
//			}
//			
//			System.exit(0);
//		}
		
	}
	
	public void showon()
	{
		setUndecorated(true);
		setResizable(false);
		setIgnoreRepaint(true);

		/*
		 * Init FSEM Mode & Create Buffer for Page Flipping
		 */
		GraphicsDevice myDevice;
		GraphicsEnvironment ge = GraphicsEnvironment
				.getLocalGraphicsEnvironment();
		myDevice = ge.getDefaultScreenDevice();
		if (!myDevice.isFullScreenSupported())
		{
			System.out.println("Full-screen exclusive mode not supported");
			shutDown(this.BACK);
		}
		try
		{
			myDevice.setFullScreenWindow(this);
			createBufferStrategy(2);
		}
		catch (Exception e)
		{
			System.out.println("Error while creating buffer strategy");
			shutDown(this.BACK);
		}

		setVisible(true);
		width = getBounds().width;
		height = getBounds().height;
		
		/*
		 * Create Objects, set their Position and action frame.
		 */
		player = new Player(6, 3);
		player.setPosition(200, 300);
		player.setFrame(width, height);
		random = new Random();
		objList = new Sprite[robotNum];
		objList[0] = player;
		
		for (int i = 1; i < objList.length; i++)
		{
			objList[i] = new Robot(6, 2);
			objList[i].setPosition(random.nextInt(width-12)+6, random.nextInt(height-12)+6);
			objList[i].setFrame(width, height);
		}

		cmdLine = new CmdLine(0,0,width, 20);

		addMouseListener(new MouseAdapter(){
			public void mousePressed(MouseEvent e)
			{
				if (isRunning && !cmdLine.isVisible())
				{
					player.setDestination(e.getX(), e.getY());
				}
			}
		});
		addKeyListener(this);
		
		startgame();
	}
	
	private void processCmd(String command)
	{
		if (command.equalsIgnoreCase("hide"))
		{
			cmdLine.setVisible(false);
		}
		if (command.equalsIgnoreCase("quit"))
		{
			shutDown(this.BACK);
		}
		if (command.equalsIgnoreCase("shutdown"))
		{
			System.exit(this.EXIT);
		}
	}

	public void startgame()
	{
		if (game == null || !isRunning)
		{
			game = new Thread(this);
			game.start();
		}
	}

	public void run()
	{
		isRunning = true;
		sleepTime = 1000/FPS;

		while (isRunning)
		{
			if (!cmdLine.isVisible())
			{
				gameUpdate();
			}
			Graphics graphics;
			myStrategy = getBufferStrategy();
			graphics = myStrategy.getDrawGraphics();
			try
			{
				graphicUpdate(graphics);
			}
			finally
			{
				graphics.dispose();
			}
			myStrategy.show();
			
			try
			{
				Thread.sleep(sleepTime);
			}
			catch (InterruptedException ie)
			{
				
			}
		}
		myStrategy.dispose();
	}

	private void gameUpdate()
	{
		if (isRunning)
		{
			/*
			 * Collision detection, not efficiency enough.
			 * 
			 */
			for (int i = 0;  i< objList.length-1; i++)
			{
				for (int j = i+1; j < objList.length; j++)
				{
					if (objList[i].collideWith(objList[j]))
					{
						objList[i].bounce(objList[j]);
						objList[j].bounce(objList[i]);
					}
				}
			}
			for (int i = 0;  i< objList.length; i++)
			{
				objList[i].move();
			}
		}
	}

	private void graphicUpdate(Graphics g)
	{
		g.setColor(Color.BLACK);
	    g.fillRect (0, 0, width, height);
	    for (int i = 0;  i< objList.length; i++)
		{
			objList[i].draw(g);
		}
	    cmdLine.draw(g);
	}

	public void keyPressed(KeyEvent e)
	{
		if (isRunning)
		{
			if (cmdLine.isVisible())
			{
				if (e.getKeyCode() == KeyEvent.VK_ENTER)
				{
					String tmp = cmdLine.getCommand();
					cmdLine.clear();
					cmdLine.record(tmp);
					processCmd(tmp);
				}
				if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE)
				{
					cmdLine.delPre();
				}
			}
			else
			{
				if (e.getKeyCode() == KeyEvent.VK_ENTER)
				{
					cmdLine.setVisible(true);
				}
			}
		}
	}
	public void keyTyped(KeyEvent e)
	{
		if (isRunning)
		{
			if (Pattern.matches("[\\w\\p{Blank}\\p{Punct}]", String.valueOf(e.getKeyChar())))
			{
				cmdLine.addCmd(e.getKeyChar());
			}
		}
	}

	public void keyReleased(KeyEvent e)
	{

	}
}
